"""LLM Plays Pokemon 游戏主循环模块"""

import time
import logging
import threading
from typing import Dict, Any, List, Optional

from llm_pokemon.emulator.pyboy import PyBoyEmulator

logger = logging.getLogger(__name__)


class SharedState:
    """游戏和核心循环之间的共享状态"""
    
    def __init__(self):
        self.running = True
        self.emulator_ready = False
        self.button_queue = []
        self.screenshot_path = None
        self.lock = threading.Lock()


class GameLoop:
    """游戏主循环类，负责处理按钮队列和与模拟器交互"""
    
    def __init__(self, config: Dict[str, Any]):
        """初始化游戏主循环
        
        Args:
            config: 系统配置
        """
        self.config = config
        self.shared_state = SharedState()
        # 直接创建PyBoyEmulator实例
        self.emulator = PyBoyEmulator(config["emulator"])
    
    def execute_button(self, button, pause_ms=None):
        """执行按钮操作
        
        Args:
            button: 要执行的按钮或按钮序列
            pause_ms: 执行后暂停的毫秒数
            
        Returns:
            执行结果
        """
        if isinstance(button, str):
            buttons = [button]
        else:
            buttons = button
            
        result = self.emulator.execute(buttons, pause_ms)
        return result
    
    def start(self, core_loop_thread):
        """启动游戏主循环
        
        Args:
            core_loop_thread: 核心循环线程实例
        """
        try:
            logger.info("启动游戏主循环...")
            
            # 启动模拟器并加载ROM
            if not self.emulator.start():
                logger.error("启动模拟器并加载ROM失败，系统退出")
                return
            
            # 设置模拟器就绪标志
            with self.shared_state.lock:
                self.shared_state.emulator_ready = True
            
            logger.info("模拟器就绪，开始游戏主循环")
            
            # 游戏主循环（处理按钮队列）
            while self.shared_state.running:
                # 检查按钮队列
                buttons_to_execute = None
                with self.shared_state.lock:
                    if self.shared_state.button_queue:
                        buttons_to_execute = self.shared_state.button_queue.pop(0)
                
                # 执行按钮操作
                if buttons_to_execute:
                    result = self.execute_button(buttons_to_execute)
                    
                    # 更新截图路径
                    with self.shared_state.lock:
                        self.shared_state.screenshot_path = result.get("screenshot")
                else:
                    # 即使没有按钮操作，也需要定期调用tick方法更新游戏画面
                    # 这是防止界面卡死的关键
                    try:
                        # 通过公共接口调用tick方法更新游戏画面
                        if self.emulator:
                            # 调用tick方法更新游戏画面
                            self.emulator.tick()
                            
                            # 移除窗口关闭检测逻辑
                    except Exception as e:
                        logger.error(f"调用tick方法失败: {e}")
                
                # 短暂暂停，避免CPU占用过高
                time.sleep(0.005)
                
        except KeyboardInterrupt:
            logger.info("用户中断，停止游戏主循环...")
            with self.shared_state.lock:
                self.shared_state.running = False
        except Exception as e:
            logger.exception(f"游戏主循环发生错误: {e}")
        finally:
            # 停止模拟器
            self.emulator.stop()
            
            # 等待核心循环线程结束
            if core_loop_thread is not None:
                logger.info("等待核心循环线程结束...")
                core_loop_thread.join(timeout=5.0)
            
            logger.info("游戏主循环已关闭")
    
    def stop(self):
        """停止游戏主循环"""
        with self.shared_state.lock:
            self.shared_state.running = False
        logger.info("游戏主循环停止信号已发送")
    
    def get_shared_state(self):
        """获取共享状态
        
        Returns:
            共享状态实例
        """
        return self.shared_state